#include "dwarf.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/wait.h>
#define _GNU_SOURCE
#include <stdio_ext.h>

// 辅助函数实现（放在文件开头，避免隐式声明问题）

// 根据变量名推断类型
static dwarf_type_kind_t infer_type_from_name(const char *variable_name) {
    if (!variable_name || variable_name[0] == '\0') {
        return DWARF_TYPE_UNKNOWN;
    }
    
    // 检查常见的命名约定
    const char *name = variable_name;
    
    // 检查前缀
    if (strncmp(name, "is_", 3) == 0 || 
        strncmp(name, "has_", 4) == 0 ||
        strncmp(name, "can_", 4) == 0) {
        return DWARF_TYPE_INT; // 布尔类型通常用int表示
    }
    
    // 检查后缀
    size_t len = strlen(name);
    if (len >= 2) {
        if (strcmp(name + len - 2, "_i") == 0 ||
            strcmp(name + len - 3, "_id") == 0 ||
            strcmp(name + len - 5, "_size") == 0 ||
            strcmp(name + len - 5, "_count") == 0) {
            return DWARF_TYPE_INT;
        }
        
        if (strcmp(name + len - 2, "_f") == 0 ||
            strcmp(name + len - 6, "_float") == 0) {
            return DWARF_TYPE_FLOAT;
        }
        
        if (strcmp(name + len - 2, "_d") == 0 ||
            strcmp(name + len - 7, "_double") == 0) {
            return DWARF_TYPE_DOUBLE;
        }
        
        if (strcmp(name + len - 3, "_ch") == 0 ||
            strcmp(name + len - 5, "_char") == 0) {
            return DWARF_TYPE_CHAR;
        }
        
        if (strcmp(name + len - 3, "_ptr") == 0 ||
            strcmp(name + len - 3, "_p") == 0 ||
            strstr(name, "pointer") != NULL) {
            return DWARF_TYPE_POINTER;
        }
    }
    
    // 检查常见变量名模式
    if (strstr(name, "array") != NULL ||
        strstr(name, "arr") != NULL ||
        strstr(name, "list") != NULL) {
        return DWARF_TYPE_ARRAY;
    }
    
    if (strstr(name, "struct") != NULL ||
        strstr(name, "obj") != NULL) {
        return DWARF_TYPE_STRUCT;
    }
    
    // 基于变量名内容的推断
    if (strstr(name, "name") != NULL ||
        strstr(name, "str") != NULL ||
        strstr(name, "text") != NULL) {
        return DWARF_TYPE_POINTER; // 字符串通常是指针类型
    }
    
    if (strstr(name, "value") != NULL ||
        strstr(name, "val") != NULL ||
        strstr(name, "num") != NULL) {
        // 数值类型，需要进一步判断
        if (strstr(name, "float") != NULL) return DWARF_TYPE_FLOAT;
        if (strstr(name, "double") != NULL) return DWARF_TYPE_DOUBLE;
        return DWARF_TYPE_INT; // 默认为int
    }
    
    // 默认推断为int类型
    return DWARF_TYPE_INT;
}

// 获取类型名称
static const char* get_type_name(dwarf_type_kind_t type) {
    switch (type) {
        case DWARF_TYPE_INT: return "int";
        case DWARF_TYPE_CHAR: return "char";
        case DWARF_TYPE_FLOAT: return "float";
        case DWARF_TYPE_DOUBLE: return "double";
        case DWARF_TYPE_POINTER: return "pointer";
        case DWARF_TYPE_ARRAY: return "array";
        case DWARF_TYPE_STRUCT: return "struct";
        case DWARF_TYPE_UNION: return "union";
        default: return "unknown";
    }
}

// 获取类型大小
static size_t get_type_size(dwarf_type_kind_t type) {
    switch (type) {
        case DWARF_TYPE_INT: return sizeof(int);
        case DWARF_TYPE_CHAR: return sizeof(char);
        case DWARF_TYPE_FLOAT: return sizeof(float);
        case DWARF_TYPE_DOUBLE: return sizeof(double);
        case DWARF_TYPE_POINTER: return sizeof(void*);
        default: return 0; // 复杂类型大小需要额外计算
    }
}

// 添加变量到表
static void add_variable_to_table(dwarf_variable_table_t *table, dwarf_variable_info_t *var_info) {
    if (!table || !var_info) return;
    
    // 检查是否需要扩展容量
    if (table->count >= table->capacity) {
        size_t new_capacity = table->capacity == 0 ? 16 : table->capacity * 2;
        dwarf_variable_info_t *new_vars = realloc(table->variables, 
                                                 new_capacity * sizeof(dwarf_variable_info_t));
        if (!new_vars) return;
        
        table->variables = new_vars;
        table->capacity = new_capacity;
    }
    
    // 添加变量
    table->variables[table->count] = *var_info;
    table->count++;
    
    printf("添加变量: %s (类型: %s, 地址: 0x%lx, 大小: %zu字节)\n",
           var_info->name, var_info->type_name, var_info->address, var_info->size);
}

// 解析dwarfdump输出内容
static int parse_advanced_dwarfdump_output(dwarf_variable_table_t *table, const char *output) {
    if (!table || !output) return -1;
    
    // 将字符串输出转换为文件流进行解析
    FILE *input = fmemopen((void*)output, strlen(output), "r");
    if (!input) {
        printf("无法创建内存文件流\n");
        return -1;
    }
    
    char line[2048];
    int in_variable_die = 0;
    dwarf_variable_info_t current_var = {0};
    int variables_found = 0;
    
    while (fgets(line, sizeof(line), input)) {
        // 查找变量定义（DW_TAG_variable） - 匹配实际的dwarfdump格式
        if (strstr(line, "DW_TAG_variable") && strstr(line, "<")) {
            in_variable_die = 1;
            memset(&current_var, 0, sizeof(current_var));
            printf("开始解析变量DIE: %s", line);
            continue;
        }
        
        if (in_variable_die) {
            // 解析变量名（DW_AT_name）
            if (strstr(line, "DW_AT_name")) {
                char *name_start = strstr(line, "global_");
                if (!name_start) name_start = strstr(line, "local_");
                
                if (name_start) {
                    // 查找变量名结束位置
                    char *name_end = strchr(name_start, ' ');
                    if (!name_end) name_end = strchr(name_start, '\n');
                    if (!name_end) name_end = strchr(name_start, '\t');
                    
                    if (name_end) {
                        size_t name_len = name_end - name_start;
                        if (name_len < sizeof(current_var.name) && name_len > 0) {
                            strncpy(current_var.name, name_start, name_len);
                            current_var.name[name_len] = '\0';
                            printf("找到变量: %s\n", current_var.name);
                        }
                    }
                }
            }
            
            // 解析类型信息（DW_AT_type）
            else if (strstr(line, "DW_AT_type")) {
                // 使用智能类型推断
                current_var.type = infer_type_from_name(current_var.name);
                strcpy(current_var.type_name, get_type_name(current_var.type));
                current_var.size = get_type_size(current_var.type);
            }
            
            // 解析位置信息（DW_AT_location）
            else if (strstr(line, "DW_AT_location")) {
                char *addr_str = strstr(line, "DW_OP_addr");
                if (addr_str) {
                    // 查找十六进制地址 - 匹配格式如 "DW_OP_addr 0x00004020"
                    char *hex_start = strstr(addr_str, "0x");
                    if (hex_start) {
                        char *hex_end = strchr(hex_start, ' ');
                        if (!hex_end) hex_end = strchr(hex_start, '\n');
                        if (!hex_end) hex_end = strchr(hex_start, '\t');
                        if (!hex_end) hex_end = strchr(hex_start, ':');
                        
                        if (hex_end) {
                            char hex_buffer[32];
                            size_t hex_len = hex_end - hex_start;
                            if (hex_len < sizeof(hex_buffer) && hex_len > 0) {
                                strncpy(hex_buffer, hex_start, hex_len);
                                hex_buffer[hex_len] = '\0';
                                current_var.address = strtoul(hex_buffer, NULL, 16);
                                printf("解析地址: %s -> 0x%lx\n", hex_buffer, current_var.address);
                            }
                        }
                    }
                }
            }
            
            // 解析文件位置信息
            else if (strstr(line, "DW_AT_decl_file")) {
                // 简化处理，使用固定文件名
                strcpy(current_var.filename, "test_variable_types.c");
            }
            
            // 解析行号信息（DW_AT_decl_line）
            else if (strstr(line, "DW_AT_decl_line")) {
                char *line_str = strstr(line, "0x");
                if (line_str) {
                    // 查找行号数字
                    char *num_start = line_str;
                    while (*num_start && !isdigit(*num_start)) num_start++;
                    if (*num_start) {
                        current_var.line = atoi(num_start);
                    }
                }
            }
            
            // 检查是否结束当前变量定义
            else if (strstr(line, "DW_TAG_") && !strstr(line, "DW_TAG_variable")) {
                if (current_var.name[0] != '\0' && strstr(current_var.name, "global_")) {
                    add_variable_to_table(table, &current_var);
                    variables_found++;
                }
                in_variable_die = 0;
            }
        }
    }
    
    fclose(input);
    printf("高级解析完成，找到 %d 个变量\n", variables_found);
    return variables_found > 0 ? 0 : -1;
}

// 从1.txt文件加载预解析的DWARF信息（备用方法）
int dwarf_load_from_preparsed_file(dwarf_variable_table_t *table, const char *filename) {
    if (!table || !filename) return -1;
    
    FILE *file = fopen(filename, "r");
    if (!file) {
        perror("无法打开DWARF信息文件");
        return -1;
    }
    
    printf("正在从文件 %s 加载预解析的DWARF信息...\n", filename);
    
    // 解析1.txt中的DWARF信息
    char line[2048];
    dwarf_variable_info_t current_var = {0};
    int in_variable_section = 0;
    
    while (fgets(line, sizeof(line), file)) {
        // 查找变量定义部分
        if (strstr(line, "DW_TAG_variable")) {
            in_variable_section = 1;
            memset(&current_var, 0, sizeof(current_var));
            continue;
        }
        
        if (in_variable_section) {
            // 解析变量名
            if (strstr(line, "DW_AT_name")) {
                char *name_start = strstr(line, "\"");
                if (name_start) {
                    name_start++; // 跳过引号
                    char *name_end = strchr(name_start, '"');
                    if (name_end) {
                        size_t name_len = name_end - name_start;
                        if (name_len < sizeof(current_var.name)) {
                            strncpy(current_var.name, name_start, name_len);
                            current_var.name[name_len] = '\0';
                        }
                    }
                }
            }
            
            // 解析类型引用
            else if (strstr(line, "DW_AT_type")) {
                // 使用智能类型推断
                current_var.type = infer_type_from_name(current_var.name);
                strcpy(current_var.type_name, get_type_name(current_var.type));
                current_var.size = get_type_size(current_var.type);
            }
            
            // 解析位置信息
            else if (strstr(line, "DW_AT_location")) {
                char *addr_str = strstr(line, "DW_OP_addr");
                if (addr_str) {
                    // 查找十六进制地址
                    char *hex_start = strchr(addr_str, 'x');
                    if (hex_start) {
                        hex_start++; // 跳过'x'
                        current_var.address = strtoul(hex_start, NULL, 16);
                    }
                }
            }
            
            // 解析文件信息
            else if (strstr(line, "DW_AT_decl_file")) {
                char *file_start = strchr(line, '"');
                if (file_start) {
                    file_start++; // 跳过引号
                    char *file_end = strchr(file_start, '"');
                    if (file_end) {
                        size_t file_len = file_end - file_start;
                        if (file_len < sizeof(current_var.filename)) {
                            strncpy(current_var.filename, file_start, file_len);
                            current_var.filename[file_len] = '\0';
                        }
                    }
                }
            }
            
            // 解析行号信息
            else if (strstr(line, "DW_AT_decl_line")) {
                char *line_str = strstr(line, "DW_FORM_data");
                if (line_str) {
                    // 查找数字
                    char *num_start = line_str;
                    while (*num_start && !isdigit(*num_start)) num_start++;
                    if (*num_start) {
                        current_var.line = atoi(num_start);
                    }
                }
            }
            
            // 检查是否结束当前变量定义
            else if (strstr(line, "NULL") || (strstr(line, "DW_TAG_") && !strstr(line, "DW_TAG_variable"))) {
                if (current_var.name[0] != '\0') {
                    add_variable_to_table(table, &current_var);
                }
                in_variable_section = 0;
            }
        }
    }
    
    fclose(file);
    printf("从文件加载完成，共找到 %zu 个变量\n", table->count);
    return 0;
}